// 文件系统服务 - Tauri API 封装

import { invoke } from '@tauri-apps/api/core';
import { FileItem, WorkspaceInfo, FileOperationResult } from '../types/filesystem';

/**
 * 文件系统服务类
 */
export class FileSystemService {
  /**
   * 读取目录内容
   */
  static async readDirectory(path: string): Promise<FileItem[]> {
    try {
      console.log('Reading directory:', path);
      const response = await invoke<any>('read_directory', { path });
      console.log('Directory response:', response);

      if (response.success) {
        return response.data || [];
      } else {
        throw new Error(response.message || 'Failed to read directory');
      }
    } catch (error) {
      console.error('Failed to read directory:', error);
      throw new Error(`Failed to read directory: ${error}`);
    }
  }

  /**
   * 读取文件内容
   */
  static async readFileContent(path: string): Promise<string> {
    try {
      const response = await invoke<any>('read_file', { path });
      if (response.success) {
        return response.data || '';
      } else {
        throw new Error(response.message || 'Failed to read file');
      }
    } catch (error) {
      console.error('Failed to read file:', error);
      throw new Error(`Failed to read file: ${error}`);
    }
  }

  /**
   * 写入文件内容
   */
  static async writeFileContent(path: string, content: string): Promise<FileOperationResult> {
    try {
      const result = await invoke<FileOperationResult>('write_file_content', { 
        path, 
        content 
      });
      return result;
    } catch (error) {
      console.error('Failed to write file:', error);
      throw new Error(`Failed to write file: ${error}`);
    }
  }

  /**
   * 创建文件
   */
  static async createFile(path: string): Promise<FileOperationResult> {
    try {
      const result = await invoke<FileOperationResult>('create_file', { path });
      return result;
    } catch (error) {
      console.error('Failed to create file:', error);
      throw new Error(`Failed to create file: ${error}`);
    }
  }

  /**
   * 创建目录
   */
  static async createDirectory(path: string): Promise<FileOperationResult> {
    try {
      const result = await invoke<FileOperationResult>('create_directory', { path });
      return result;
    } catch (error) {
      console.error('Failed to create directory:', error);
      throw new Error(`Failed to create directory: ${error}`);
    }
  }

  /**
   * 删除文件或目录
   */
  static async deleteFileOrDirectory(path: string): Promise<FileOperationResult> {
    try {
      const result = await invoke<FileOperationResult>('delete_file_or_directory', { path });
      return result;
    } catch (error) {
      console.error('Failed to delete:', error);
      throw new Error(`Failed to delete: ${error}`);
    }
  }

  /**
   * 重命名文件或目录
   */
  static async renameFileOrDirectory(oldPath: string, newPath: string): Promise<FileOperationResult> {
    try {
      const result = await invoke<FileOperationResult>('rename_file_or_directory', { 
        oldPath, 
        newPath 
      });
      return result;
    } catch (error) {
      console.error('Failed to rename:', error);
      throw new Error(`Failed to rename: ${error}`);
    }
  }

  /**
   * 检查路径是否存在
   */
  static async pathExists(path: string): Promise<boolean> {
    try {
      const files = await this.readDirectory(path);
      return true;
    } catch {
      return false;
    }
  }

  /**
   * 获取工作区信息
   */
  static async getWorkspaceInfo(path: string): Promise<WorkspaceInfo> {
    try {
      const files = await this.readDirectory(path);
      const workspaceName = path.split('/').pop() || path.split('\\').pop() || 'Workspace';
      
      return {
        path,
        name: workspaceName,
        files,
      };
    } catch (error) {
      console.error('Failed to get workspace info:', error);
      throw new Error(`Failed to get workspace info: ${error}`);
    }
  }

  /**
   * 递归读取目录结构
   */
  static async readDirectoryRecursive(
    path: string, 
    maxDepth: number = 3,
    currentDepth: number = 0
  ): Promise<FileItem[]> {
    if (currentDepth >= maxDepth) {
      return [];
    }

    try {
      const files = await this.readDirectory(path);
      const allFiles: FileItem[] = [...files];

      // 递归读取子目录
      for (const file of files) {
        if (file.is_directory) {
          try {
            const subFiles = await this.readDirectoryRecursive(
              file.path, 
              maxDepth, 
              currentDepth + 1
            );
            allFiles.push(...subFiles);
          } catch (error) {
            // 忽略无法访问的目录
            console.warn(`Cannot access directory: ${file.path}`);
          }
        }
      }

      return allFiles;
    } catch (error) {
      console.error('Failed to read directory recursively:', error);
      throw new Error(`Failed to read directory recursively: ${error}`);
    }
  }

  /**
   * 搜索文件
   */
  static async searchFiles(
    basePath: string, 
    query: string, 
    options: {
      includeContent?: boolean;
      fileExtensions?: string[];
      maxResults?: number;
    } = {}
  ): Promise<FileItem[]> {
    const { includeContent = false, fileExtensions, maxResults = 100 } = options;
    
    try {
      const allFiles = await this.readDirectoryRecursive(basePath);
      let results = allFiles.filter(file => {
        // 文件名匹配
        const nameMatch = file.name.toLowerCase().includes(query.toLowerCase());
        
        // 扩展名过滤
        const extensionMatch = !fileExtensions || 
          (file.extension && fileExtensions.includes(file.extension));
        
        return nameMatch && extensionMatch && !file.is_directory;
      });

      // 如果需要搜索文件内容
      if (includeContent) {
        const contentMatches: FileItem[] = [];
        
        for (const file of results.slice(0, 50)) { // 限制内容搜索的文件数量
          try {
            const content = await this.readFileContent(file.path);
            if (content.toLowerCase().includes(query.toLowerCase())) {
              contentMatches.push(file);
            }
          } catch {
            // 忽略无法读取的文件
          }
        }
        
        // 合并结果并去重
        const allMatches = [...results, ...contentMatches];
        const uniqueMatches = allMatches.filter((file, index, array) => 
          array.findIndex(f => f.path === file.path) === index
        );
        
        results = uniqueMatches;
      }

      // 限制结果数量
      return results.slice(0, maxResults);
    } catch (error) {
      console.error('Failed to search files:', error);
      throw new Error(`Failed to search files: ${error}`);
    }
  }

  /**
   * 批量操作
   */
  static async batchOperation(
    operations: Array<{
      type: 'create' | 'delete' | 'rename';
      path: string;
      newPath?: string;
      isDirectory?: boolean;
    }>
  ): Promise<FileOperationResult[]> {
    const results: FileOperationResult[] = [];

    for (const operation of operations) {
      try {
        let result: FileOperationResult;

        switch (operation.type) {
          case 'create':
            result = operation.isDirectory 
              ? await this.createDirectory(operation.path)
              : await this.createFile(operation.path);
            break;
          case 'delete':
            result = await this.deleteFileOrDirectory(operation.path);
            break;
          case 'rename':
            if (!operation.newPath) {
              throw new Error('New path is required for rename operation');
            }
            result = await this.renameFileOrDirectory(operation.path, operation.newPath);
            break;
          default:
            throw new Error(`Unknown operation type: ${operation.type}`);
        }

        results.push(result);
      } catch (error) {
        results.push({
          success: false,
          message: `Failed to ${operation.type}: ${error}`,
          path: operation.path,
        });
      }
    }

    return results;
  }

  /**
   * 获取文件统计信息
   */
  static async getFileStats(path: string): Promise<{
    totalFiles: number;
    totalDirectories: number;
    totalSize: number;
    filesByExtension: Record<string, number>;
  }> {
    try {
      const files = await this.readDirectoryRecursive(path);
      
      let totalFiles = 0;
      let totalDirectories = 0;
      let totalSize = 0;
      const filesByExtension: Record<string, number> = {};

      files.forEach(file => {
        if (file.is_directory) {
          totalDirectories++;
        } else {
          totalFiles++;
          totalSize += file.size || 0;
          
          const ext = file.extension || 'no-extension';
          filesByExtension[ext] = (filesByExtension[ext] || 0) + 1;
        }
      });

      return {
        totalFiles,
        totalDirectories,
        totalSize,
        filesByExtension,
      };
    } catch (error) {
      console.error('Failed to get file stats:', error);
      throw new Error(`Failed to get file stats: ${error}`);
    }
  }
}
